import java.util.concurrent.*;

public class Main820 {
    public static void main(String[] args) {
        /*
            四大内置线程池
            CachedThreadPool   ---  线程存储队列 SynchronousQueue
            FixedThreadPool   ---  线程存储队列 LinkedBlockingQueue
            ScheduledThreadPool   ---  线程存储队列 DelayedWorkQueue ,DelayedWorkQueue 是 ScheduledThreadPool 的内部实现
            SingleThreadScheduledExecutor --- DelayedWorkQueue
            以上这些线程池都是使用 ThreadPoolExecutor 创建的，只是使用了不同的排队方式 BlockQueue，看
                直接交接。 工作队列的一个很好的默认选择是SynchronousQueue ，它可以将任务交给线程，而不会保留它们。 在这里，如果没有线程立即可用于运行它，则尝试对任务进行排队将失败，因此将构造新线程。 此策略在处理可能具有内部依赖性的请求集时避免了锁定。 直接切换通常需要无限制的maximumPoolSizes以避免拒绝新提交的任务。 这反过来承认，当命令继续以比处理它们更快的速度到达时，无限制的线程增长的可能性。
                无限队列。 使用无界队列（例如，没有预定义容量的LinkedBlockingQueue ）将导致新任务在所有corePoolSize线程忙时在队列中等待。 因此，只会创建corePoolSize线程。 （并且maximumPoolSize的值因此没有任何影响。）当每个任务完全独立于其他任务时，这可能是适当的，因此任务不会影响彼此的执行; 例如，在网页服务器中。 虽然这种排队方式可以有助于平滑瞬态突发请求，但它承认，当命令继续平均到达的速度超过可处理速度时，无限制的工作队列增长的可能性。
                有限的队列。 有限队列（例如， ArrayBlockingQueue ）在与有限maximumPoolSizes一起使用时有助于防止资源耗尽，但可能更难以调整和控制。 队列大小和最大池大小可以相互交换：使用大型队列和小型池最小化CPU使用率，OS资源和上下文切换开销，但可能导致人为的低吞吐量。 如果任务经常阻塞（例如，如果它们是I / O绑定的），则系统可能能够为您提供比您允许的更多线程的时间。 使用小队列通常需要更大的池大小，这会使CPU更加繁忙，但可能会遇到不可接受的调度开销，这也会降低吞吐量。
            源码看就可以知道
            阿里规范是不建议使用 Executors 去创建现成的，因为这样对线程不够明确，阿里建议使用 ThreadPoolExecutor 去创建，
            但是 Java 推荐使用 Executors,仅作了解

            ScheduledThreadPool 是继承了 ThreadPoolExecutor 重写了父类构造方法
            而 SingleThreadScheduledExecutor 则是线程池只有一个线程的池子 看源码
         */


        ExecutorService cachedThreadPool = new ThreadPoolExecutor(
                3,
                7,
                60, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());

        ExecutorService fixdThreadPool = new ThreadPoolExecutor(
                3,
                7,
                60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3));


        ExecutorService scheduledThreadPool = new ThreadPoolExecutor(
                3,
                7,
                60, TimeUnit.SECONDS,
                new DelayQueue());

        ExecutorService singleScheduledThreadPool = new ScheduledThreadPoolExecutor(1);
        // cache
        {
            cachedThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("cache 1");
                    }
                }
            });
            cachedThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("cache 2");
                    }
                }
            });
            cachedThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("cache 3");
                    }
                }
            });
            cachedThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("cache 4");
                    }
                }
            });
        }

        // fixd
        {
            fixdThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("fixed 1");
                    }
                }
            });
            fixdThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("fixed 2");
                    }
                }
            });
            fixdThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("fixed 3");
                    }
                }
            });
            fixdThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("fixed 4");
                    }
                }
            });
        }
        // scheduledThreadPool
        {
            scheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("scheduledThreadPool 1");
                    }
                }
            });
            scheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("scheduledThreadPool 2");
                    }
                }
            });
            scheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("scheduledThreadPool 3");
                    }
                }
            });
            scheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("scheduledThreadPool 4");
                    }
                }
            });
        }
        // singleScheduledThreadPool
        {
            singleScheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("s 1");
                    }
                }
            });
            singleScheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("s 2");
                    }
                }
            });
            singleScheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("s 3");
                    }
                }
            });
            singleScheduledThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000;i++){
                        System.out.println("s 4");
                    }
                }
            });
        }
    }
}
